001 /* 002 * Copyright 2005 Stephen J. McConnell 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 013 * implied. 014 * 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 019 package net.dpml.library.impl; 020 021 import java.util.ArrayList; 022 import java.util.Enumeration; 023 import java.util.Properties; 024 025 import net.dpml.library.Dictionary; 026 import net.dpml.library.info.AbstractDirective; 027 028 import net.dpml.util.PropertyResolver; 029 030 /** 031 * Utility class used for construction of a module model from an XML source. 032 * 033 * @author <a href="http://www.dpml.net">The Digital Product Meta Library</a> 034 * @version 1.0.0 035 */ 036 public class DefaultDictionary implements Dictionary 037 { 038 private final DefaultDictionary m_parent; 039 private final AbstractDirective m_directive; 040 private final Properties m_properties; 041 042 /** 043 * Creation of a new dictionary. The dictionary provides support 044 * for property inheritance within the hierachy of of modules based 045 * an a single root virtual module. When handling a propety request 046 * the dictionary will attempt to resolve the property value using 047 * local property values. If the value is unresolved, the implemenetation 048 * will attempt to delegate the request to a parent dictionary if available. 049 * 050 * @param parent the parent dictionary (possibly null) 051 * @param directive an abstract directive containing local properties 052 */ 053 public DefaultDictionary( DefaultDictionary parent, AbstractDirective directive ) 054 { 055 if( null == directive ) 056 { 057 throw new NullPointerException( "directive" ); 058 } 059 m_parent = parent; 060 m_directive = directive; 061 062 Properties properties = getParentProperties(); 063 m_properties = new Properties( properties ); 064 Properties local = directive.getProperties(); 065 String[] keys = getLocalPropertyNames( local ); 066 for( int i=0; i<keys.length; i++ ) 067 { 068 String key = keys[i]; 069 String value = local.getProperty( key ); 070 m_properties.setProperty( key, value ); 071 } 072 } 073 074 //---------------------------------------------------------------------------- 075 // Dictionary 076 //---------------------------------------------------------------------------- 077 078 /** 079 * Return the property names associated with the dictionary. 080 * @return the array of property names 081 */ 082 public String[] getPropertyNames() 083 { 084 return getLocalPropertyNames( m_properties ); 085 } 086 087 /** 088 * Return the local property names associated with the dictionary. 089 * @return the array of local property names 090 */ 091 public String[] getLocalPropertyNames() 092 { 093 return getLocalPropertyNames( m_directive.getProperties() ); 094 } 095 096 /** 097 * Return a property value. 098 * @param key the property key 099 * @return the property value 100 */ 101 public String getProperty( String key ) 102 { 103 return getProperty( key, null ); 104 } 105 106 /** 107 * Return a property value. 108 * @param key the property key 109 * @param value the default value 110 * @return the property value 111 */ 112 public String getProperty( String key, String value ) 113 { 114 String result = m_properties.getProperty( key, value ); 115 return resolve( result ); 116 } 117 118 /** 119 * Return an integer property value. 120 * @param key the property key 121 * @param value the default value 122 * @return the property value as an integer 123 * @exception NumberFormatException if underlying property value 124 * cannot be resolved to an integer 125 */ 126 public int getIntegerProperty( String key, int value ) 127 { 128 String result = m_properties.getProperty( key ); 129 if( null == result ) 130 { 131 return value; 132 } 133 else 134 { 135 String literal = resolve( result ); 136 return Integer.parseInt( literal ); 137 } 138 } 139 140 /** 141 * Return an boolean property value. 142 * @param key the property key 143 * @param value the default value 144 * @return the property value as an boolean 145 * @exception NumberFormatException if underlying property value 146 * cannot be resolved to an integer 147 */ 148 public boolean getBooleanProperty( String key, boolean value ) 149 { 150 String result = m_properties.getProperty( key ); 151 if( null != result ) 152 { 153 return Boolean.valueOf( result ).booleanValue(); 154 } 155 else 156 { 157 return value; 158 } 159 } 160 /** 161 * Evaluate and expand any symbolic references in the supplied value. 162 * @param value the value to resolve 163 * @return the resolved value 164 */ 165 public String resolve( String value ) 166 { 167 return PropertyResolver.resolve( m_properties, value ); 168 } 169 170 //---------------------------------------------------------------------------- 171 // internal 172 //---------------------------------------------------------------------------- 173 174 void setProperty( String name, String value ) 175 { 176 m_properties.setProperty( name, value ); 177 } 178 179 AbstractDirective getAbstractDirective() 180 { 181 return m_directive; 182 } 183 184 Properties getProperties() 185 { 186 return m_properties; 187 } 188 189 private Properties getParentProperties() 190 { 191 if( null == m_parent ) 192 { 193 return new Properties(); 194 } 195 else 196 { 197 return m_parent.getProperties(); 198 } 199 } 200 201 private String[] getLocalPropertyNames( Properties properties ) 202 { 203 ArrayList list = new ArrayList(); 204 Enumeration names = properties.propertyNames(); 205 while( names.hasMoreElements() ) 206 { 207 list.add( (String) names.nextElement() ); 208 } 209 return (String[]) list.toArray( new String[0] ); 210 } 211 212 Properties getExportProperties() 213 { 214 String[] keys = getLocalPropertyNames(); 215 Properties properties = new Properties(); 216 for( int i=0; i<keys.length; i++ ) 217 { 218 String key = keys[i]; 219 String value = getProperty( key ); 220 properties.setProperty( key, value ); 221 } 222 return properties; 223 } 224 }